package com.sg.file.web;

import com.sg.common.model.ResultModel;
import com.sg.common.utils.ResultModelUtils;
import com.sg.file.common.FileCodeEnum;
import com.sg.file.receive.api.IFileManagerService;
import com.sg.file.receive.api.IFileReceiveService;
import com.sg.file.receive.api.dto.ByteFileReceiveRequest;
import com.sg.file.receive.api.dto.FileReceiveResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * 文件上传controller，用于接收上传的文件
 * ClassName:FileUploadController <br/>
 * Function: ADD FUNCTION. <br/>
 * Reason:   ADD REASON. <br/>
 * Update：      201807
 * @author   xzk
 * @version
 * @since    JDK 1.8
 * @see
 */
@CrossOrigin
@RestController
@RequestMapping("/file")
public class FileManagerController {
    @Autowired
    private IFileReceiveService localFileReceive;
    @Autowired
    private IFileManagerService fileManagerService;

    /**
     * 文件上传
     * @param request
     * @param response
     * @param proPath
     * @return
     */
    @RequestMapping(value="/upload",method={RequestMethod.POST, RequestMethod.GET})
    public ResultModel upload(HttpServletRequest request, HttpServletResponse response
            , @RequestParam(value="proPath",required=false)String proPath){
        //写入文件
        return fileReceive(request,proPath,null);
    }

    /**
     * 文件上传（Restful）
     * @param request
     * @param response
     * @param proPath
     * @return
     */
    @RequestMapping(value="/upload/{proPath}",method={RequestMethod.POST})
    public ResultModel restUpload(HttpServletRequest request, HttpServletResponse response,
                                  @PathVariable("proPath")String proPath){
        return upload(request,response,proPath);
    }


    /**
     * 文件更新
     * @param request
     * @param response
     * @param fileId
     * @return
     */
    @RequestMapping(value = "/update",method = {RequestMethod.POST})
    public ResultModel updateFileById(HttpServletRequest request,HttpServletResponse response,
                                      @RequestParam(value = "fileId") String fileId){
        return fileReceive(request,null,fileId);
    }

    /**
     * 文件更新（Restful）
     * @param request
     * @param response
     * @param fileId
     * @return
     */
    @RequestMapping(value = "/update/{fileId}",method = {RequestMethod.POST})
    public ResultModel RestUpdateFileById(HttpServletRequest request,HttpServletResponse response,
                                      @PathVariable("fileId") String fileId){
        return fileReceive(request,null,fileId);
    }



    /**
     * 文件更新（Restful）
     * @param request
     * @param response
     * @param fileId
     * @return
     */
    @RequestMapping(value = "/delete/{fileId}",method = {RequestMethod.POST})
    public ResultModel RestDeleteFileById(HttpServletRequest request,HttpServletResponse response,
                                          @PathVariable("fileId") String fileId){
        return fileManagerService.delete(fileId);
    }

    /**
     * 文件更新
     * @param request
     * @param response
     * @param fileId
     * @return
     */
    @RequestMapping(value = "/delete",method = {RequestMethod.POST})
    public ResultModel deleteFileById(HttpServletRequest request,HttpServletResponse response,
                                      @RequestParam(value = "fileId") String fileId){
        return fileManagerService.delete(fileId);
    }


    /**
     * 文件接收
     * @param request
     * @param proPath
     * @return
     */
    private ResultModel fileReceive(HttpServletRequest request, String proPath,String fileId){
        ResultModel resultModel = ResultModelUtils.getInstance();
        List<ByteFileReceiveRequest> fileReceiveRequestList = getFile(request,proPath);
        //判断 request 是否有文件上传
        if (CollectionUtils.isEmpty(fileReceiveRequestList)){
            resultModel.setSuccess(true);
            resultModel.setErrorCode(FileCodeEnum.NO_FILE_RECEIVE.getCode());
            resultModel.setMessage(FileCodeEnum.NO_FILE_RECEIVE.getMessage());
            return resultModel;
        }
        FileReceiveResponse fileReceiveResponse = null;
        if(StringUtils.isEmpty(fileId)) {
            fileReceiveResponse = localFileReceive.receiveAndAdd(fileReceiveRequestList);
        }else{
            //文件更新是只会更新一个文件，所以取0
            ByteFileReceiveRequest byteFileReceiveRequest = fileReceiveRequestList.get(0);
            byteFileReceiveRequest.setFileId(fileId);
            fileReceiveResponse = localFileReceive.receiveAndUpdate(byteFileReceiveRequest);
        }

        return ResultModelUtils.getSuccessInstance(fileReceiveResponse);
    }

    /**
     * 从请求中获取文件
     * @param request
     * @param proPath
     * @return
     */
    private List<ByteFileReceiveRequest> getFile(HttpServletRequest request,String proPath){
        //创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //转换成多部分request
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        //取得request中的所有文件名
        Iterator<String> iter = multiRequest.getFileNames();
        //创建解析集合
        List<ByteFileReceiveRequest> fileReceiveRequestList = new ArrayList<>();
        while (iter.hasNext()) {
            //取得上传文件
            MultipartFile file = multiRequest.getFile(iter.next());
            if(file==null){
                continue;
            }
            try {
                ByteFileReceiveRequest fileReceiveRequest = ByteFileReceiveRequest.builder().fileByte(file.getBytes()).
                        fileName(file.getOriginalFilename()).
                        contentType(file.getContentType()).
                        proName(proPath).
                        fileSize(file.getSize()).build();
                fileReceiveRequestList.add(fileReceiveRequest);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileReceiveRequestList;
    }
}
